package dd.prog2.musterExercises.ws12set12;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import dd.prog2.musterExercises.ws12set01_connectfour.Board;
import dd.prog2.musterExercises.ws12set01_connectfour.Disk;
import dd.prog2.musterExercises.ws12set01_connectfour.Game;

/**
 * Provides a very simple GUI for the Connect Four game. It uses changing
 * background colors of buttons to visualize disks. All buttons are organized in
 * an array and the index is used to identify the position in the board. As
 * action listener, a central object - realized as inner class - is used.
 * 
 * @author Ruediger Lunde
 * 
 */
public class ConnectFourAppV1 {

	// create attributes for all parts of the application which need to be
	// accessed by listeners, inner classes, and helper methods

	private JFrame frame;
	private JPanel boardPanel;
	private JButton clearButton;
	private JButton[] boardButtons;
	private JLabel statusBar;

	private Game game;

	/** Creates a game object, constructs the game frame and makes it visible. */
	public void start() {
		game = new Game();

		frame = new JFrame("Connect Four V1");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		AppActionListener listener = new AppActionListener();
		clearButton = new JButton("Clear");
		clearButton.addActionListener(listener);
		frame.add(clearButton, BorderLayout.NORTH);

		int rows = game.getBoard().getRows();
		int cols = game.getBoard().getCols();
		boardPanel = new JPanel();
		boardPanel.setLayout(new GridLayout(rows, cols, 5, 5));
		boardPanel.setBorder(BorderFactory.createEtchedBorder());
		boardPanel.setBackground(Color.BLUE);
		boardButtons = new JButton[rows * cols];
		for (int i = 0; i < rows * cols; i++) {
			JButton button = new JButton();
			button.addActionListener(listener);
			boardButtons[i] = button;
			boardPanel.add(button);
		}
		frame.add(boardPanel, BorderLayout.CENTER);
		statusBar = new JLabel();
		frame.getContentPane().setBackground(Color.BLUE);
		statusBar.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		frame.add(statusBar, BorderLayout.SOUTH);

		update();
		frame.setSize(400, 400);
		frame.setVisible(true);
	}

	/** Updates the view. */
	private void update() {
		Board board = game.getBoard();
		for (int i = 0; i < boardButtons.length; i++) {
			Disk d = board.getDiskAt(i / board.getCols(), i % board.getCols());
			Color color = Color.BLUE;
			if (d != null)
				color = d.getColor().equals("red") ? Color.RED : Color.YELLOW;
			boardButtons[i].setBackground(color);
		}
		if (!game.isGameOver()) {
			String toMove = game.getNextPlayerColor();
			statusBar.setText("Next move: " + toMove);
			statusBar.setForeground(toMove.equals("red") ? Color.RED
					: Color.YELLOW);
		} else if (game.getWinner() != null){
			statusBar.setText("Color " + game.getWinner() + " has won. Congratulations!");
			statusBar.setForeground(Color.WHITE);
		} else {
			statusBar.setText("No winner :-(");
		}
	}

	/** Creates the Connect Four Application and starts it. */
	public static void main(String[] args) {
		ConnectFourAppV1 gameApp = new ConnectFourAppV1();
		gameApp.start();
	}

	// ///////////////////////////////////////////////////////////////////
	// inner classes

	/** Defines the reactions on grid element events. */
	private class AppActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == clearButton) {
				game = new Game(); // start a new game
			} else if (!game.isGameOver()) {
				// make next move
				for (int i = 0; i < boardButtons.length; i++)
					if (e.getSource() == boardButtons[i])
						game.makeMove(i % game.getBoard().getCols());
			}
			boardPanel.repaint(); // paint all disks!
			update();
		}
	}
}
